#include <iostream>
#include "net/proactor_engine.hpp"

using namespace shine;
using namespace shine::net;

int main(){

    std::cout << "bind address: ";
    shine::string addr = "0.0.0.0:9000";
//     std::cin >> addr;

    proactor_engine engine;
	acceptor * rc = engine.add_acceptor("echo_server", addr, [&engine](bool status, connection *conn)->bool{
        if (status)
        {
            conn->set_recv_timeout(0);

            conn->register_recv_callback([](const int8 *data, shine::size_t len, connection *conn)->bool{
                conn->async_send(data, len);
                return true;
            });

            conn->async_recv();
        }

        return true;
    });

	engine.get_timer().set_timer(2000, [rc]()->bool {
		new std::thread([rc] {
			std::this_thread::sleep_for(std::chrono::seconds(2));
			std::function<void()> func = [rc] {
				//BOOL rc1 = CancelIoEx((HANDLE)rc->get_socket_fd(), NULL);
				shine::net::socket::close(rc->get_socket_fd());
				//shine::net::socket::shutdown(rc->get_socket_fd(), SD_BOTH);

				std::cout << HasOverlappedIoCompleted(&rc->get_recv_context()) << std::endl;
				std::cout << HasOverlappedIoCompleted(&rc->get_send_context()) << std::endl;
			};
			// 				conn->get_engine()->queue_execute(func);
			func();
		});
		return false;
	});

    if (rc)
    {
        std::cout << "bind " << addr << "success." << endl;
        engine.run();
    }
    else
    {
        std::cout << "bind " << addr << "failed." << endl;
    }

    return 0;
}